home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Other Stuff
/
Other Stuff ’97
/
PowerOS Development
/
booter
/
elf_makeimage.c
< prev
next >
Wrap
Text File
|
1997-06-26
|
4KB
|
155 lines
/*
elf_makeimage.c
copyright 1996-1997 by Ben Martz
all rights reserved world wide
ANY AND ALL MODIFICATIONS TO THIS SOURCE MUST CREDIT THE ORIGINAL
AUTHOR, BEN MARTZ (benmartz@ic.net), AND MUST BE GIVEN TO THE AUTHOR
FOR INTEGRATION INTO THE MAIN PowerOS SOURCE TREE. THANK YOU FOR YOUR
COOPERATION!
This program takes a PowerPC ELF binary and converts it to an image
that can be loaded into memory and executed directly.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "elf_format.h"
long elf_makeimage(char *fname, char **kptr);
long elf_makeimage(char *fname, char **kptr) {
char *kerneldata;
char filename[256];
OSErr err;
FSSpec spec;
FInfo fndrInfo;
short file,count;
long filelen, len, offset, i;
char *filedata;
Elf32_Hdr *header;
Elf32_Shdr *sheader;
UInt32 text_start = 0;
UInt32 last_start = 0,last_offset,last_size;
UInt32 sect_start = 0,sect_offset,sect_size;
long totallen = 0;
/* convert c to p str */
strcpy(filename+1,fname);
filename[0] = strlen(filename+1);
/* open and read in the binary file */
err = FSMakeFSSpec(0,0,(unsigned char *)filename,&spec);
if(err != noErr) return -1;
/* fix creator and type */
err = FSpGetFInfo(&spec,&fndrInfo);
if(err == noErr) {
fndrInfo.fdType = 'elf ';
fndrInfo.fdCreator = 'pos ';
FSpSetFInfo(&spec,&fndrInfo);
}
err = FSpOpenDF(&spec,fsRdPerm,&file);
if(err != noErr) return -1;
err = GetEOF(file,&filelen);
if(err != noErr) return -1;
filedata = NewPtrClear(filelen);
if(!filedata) return -1;
len = filelen;
err = FSRead(file,&len,filedata);
if(err != noErr) return -1;
if(len != filelen) return -1;
FSClose(file);
header = (Elf32_Hdr *) filedata;
/* make sure that this is a binary file that we can handle! */
if((header->ei_magic[1] != 'E') || (header->ei_magic[2] != 'L') || (header->ei_magic[3] != 'F')) return -1;
if(header->ei_version != 1) return -1;
if(header->e_machine != EM_PPC601) return -1;
if(!header->e_shnum) return -1;
/* find the program sections */
/* read through once to find the memory size to allocate */
last_start = last_offset = last_size = 0L;
for(count = 0; count < header->e_shnum; count++) {
sect_start = sect_offset = sect_size = 0L;
offset = header->e_shoff + (header->e_shentsize * count);
if(offset < (long)(filedata + filelen - sizeof(Elf32_Shdr))) {
sheader = (Elf32_Shdr *) (filedata + offset);
if(sheader->sh_type == SHT_PROGBITS) {
sect_start = sheader->sh_addr;
sect_offset = sheader->sh_offset;
sect_size = sheader->sh_size;
if(sect_start > last_start + last_size) {
/* pad with zero */
len = sect_start - (last_start + last_size);
totallen += len;
}
if(sheader->sh_flags == SECT_TEXT) text_start = sect_start;
len = sect_size;
totallen += len;
last_start = sect_start;
last_offset = sect_offset;
last_size = sect_size;
}
}
}
kerneldata = NewPtrClear(totallen);
if(!kerneldata) return -1;
*kptr = kerneldata;
/* extract the sections now */
totallen = 0;
last_start = last_offset = last_size = 0L;
for(count = 0; count < header->e_shnum; count++) {
sect_start = sect_offset = sect_size = 0L;
offset = header->e_shoff + (header->e_shentsize * count);
if(offset < (long)(filedata + filelen - sizeof(Elf32_Shdr))) {
sheader = (Elf32_Shdr *) (filedata + offset);
if(sheader->sh_type == SHT_PROGBITS) {
sect_start = sheader->sh_addr;
sect_offset = sheader->sh_offset;
sect_size = sheader->sh_size;
if(sect_start > last_start + last_size) {
/* pad with zero */
len = sect_start - (last_start + last_size);
totallen += len;
while(len--) *((char *)(kerneldata++)) = '\0';
}
if(sheader->sh_flags == SECT_TEXT) text_start = sect_start;
len = sect_size;
totallen += len;
for(i = 0; i < len; i++) {
*((char *)(kerneldata++)) = *((char *) filedata+sect_offset+i);
}
last_start = sect_start;
last_offset = sect_offset;
last_size = sect_size;
}
}
}
return totallen;
} /* end of main */